/*
Flexperimentos.
Copyright (C) 2007  Richard R Manzke

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package br.absolutobrasil.validators
{
	import mx.validators.ValidationResult;
	import mx.validators.Validator;

	public class CPFValidator extends Validator
	{
		include "../core/Versao.as";	
		        /**
     				 * CPFValidator
  					 * @author Richard R Manzke <tuco.net@gmail.com>
       			     * @langversion ActionScript 3.0
                 */
               private var results:Array;
              private const CPF_LENGTH:int = 11;
		public function CPFValidator()
		{
			 super();
		}
  override protected function doValidation(value:Object):Array{
                   var cpf:String = String(value);
                 results = [];
                   
                        // Super classe é chamada para verificação de campo requerido.
                  results = super.doValidation(value);
                    if (results.length > 0)
                         return results;
                         
                        // Verifica se o CPF tem comprimento correto.
                   if (cpf.length != CPF_LENGTH && value){
                         results.push(new  ValidationResult(true, null, "invalido", "O CPF tem tamanho inválido."));
                              return results;
                 }
                       
                        // Verifica se o CPF é um número.
                       var pattern:RegExp = new RegExp("\\d{11}", "");
                 if (!pattern.test(cpf)){
                                results.push(new ValidationResult(true, null, "NaN", "O CPF não é um número."));
                                return results;
                 }
                       
                        // Confere os dígitos verificadores
                     if (!ConfereDigitos(cpf) && value){
                             results.push(new ValidationResult(true, null, "Invalido", "O CPF é inválido!"));                                
                                return results;
                 }
                       return results;
         }
               
                /**
              * Confere os digitos verificadores de um CPF.
           * @param nrCPF Número do CPF
            * @return O valor retornado será <code>true</code> se a verificação de digitos for verdadeira;
          */
             private function ConfereDigitos(nrCPF:String):Boolean{
                  
                        if (nrCPF.length != CPF_LENGTH)
                         return false;
                   
                        var cpf:String = nrCPF;
                 var multiplicador:Array = [10,9,8,7,6,5,4,3,2];
                 var digito1:Number = Number(cpf.charAt(9));
                     var digito2:Number = Number(cpf.charAt(10));
                    var r:Number = 0;
                       
                        // Calculo do primeiro digito
                   for (var i:int = 0; i < multiplicador.length; i++){
                             r += Number(cpf.charAt(i)) * multiplicador[i];
                          multiplicador[i] += 1;
                  }
                       r %= 11;
                        r = r < 2 ? 0 : 11 - r;
                 if (r != digito1)
                               return false;
                           
                        // Calculo do segundo digito
                    multiplicador.push(2);
                  r = 0;
                  for (i = 0; i < multiplicador.length; i++){
                             r += Number(cpf.charAt(i)) * multiplicador[i];
                  }
                       r %= 11;
                        r = r < 2 ? 0 : 11 - r;
                 if (r == digito2)
                               return true;
                    else
                            return false;
           }	
	}
}